//
// Created by Never on 2019/8/6.
//

#ifndef MODELFORLRP_READINSTANCE_H
#define MODELFORLRP_READINSTANCE_H

#include<cmath>
#include <iostream>
#include<fstream>
#include"json/json.h"
#include "CVRPMD_Parameter.h"
#include "Instance.h"
#include "DefineProblemType.h"
#if defined(LRP)
//TODO: reading Instance and handling instance should be splited and handling instance should not belong to this class.
class ReadLRPInstance {
private:
    CVRPMDStructure::Depots depots;
    CVRPMDStructure::Customers customers;
    string type;
    int vehicleCapacity;
    int vehicleCosts;
    string filename;
    int depot_count;
    int customer_count;
    vector<vector<DisType>> distance;
    // for depots, it denotes capacity and for customers, it denotes demand.
    vector<int> nodesDemand;
    vector<int> depotsCost;
    string name;
    vector<int> vehicleNumberInEachDepotByDividingDepotCapByVehicleCap;

    void checkDepotIndex(int depotIndex);
    void readInstance();
    void computeDistances();
    void assignDepotsCapacity();
    void assignDepotsCost();
public:
    ReadLRPInstance(string &filename): filename(filename){
        readInstance();
        depot_count = depots.size();
        customer_count = customers.size();
        distance = vector<vector<DisType>>(depot_count+customer_count,vector<DisType>(depot_count + customer_count,0));
        computeDistances();
        nodesDemand.resize(depot_count+customer_count);
        depotsCost.resize(depot_count);
        assignDepotsCapacity();
        assignDepotsCost();
        computeVehicleNumberInEachDepotByDividingDepotCapByVehicleCap();
    }
    Instance obtainInstance() const;
    // following members are used to obtain elements in the instance.
    const string &getType() const;
    int getVehicleCapacity() const;
    int getVehicleCosts() const;
    void printInstance();
    int getDepotCount() const;
    int getCustomerCount() const;
    const vector<vector<DisType>> &getDistance() const;
    const vector<int> &getNodesDemand() const;
    const vector<int> &getDepotsCost() const;
    const string &getName() const;

    // TODO: following members are used to for the model and they should be moved out
    const CVRPMDStructure::Depots &getDepots() const;
    const CVRPMDStructure::Customers &getCustomers() const;
    void setDepotVehicleNumber(int depotIndex, int vehicleNumber);
    void setDepotState(int depotIndex, bool isOpen);
    void changeDepotsState(vector<bool> isopen, vector<int> vehicleNumber);
    const void computeVehicleNumberInEachDepotByDividingDepotCapByVehicleCap();
    const vector<int> getVehicleNumberInEachDepotByDividingDepotCapByVehicleCap() const;
    int getVehicleCount() const;
};

#endif
#endif //MODELFORLRP_READINSTANCE_H
